<template>
  <div class="chapter-manager">
    <div class="chapter-manager-btns">
      <el-tooltip effect="dark" content="新建卷" placement="bottom" show-after="2000">
        <el-icon @click="clickAddVolume"><i-ep-FolderAdd /></el-icon>
      </el-tooltip>
      <el-tooltip effect="dark" content="新建章" placement="bottom" show-after="2000">
        <el-icon @click="clickAddChapter"><i-ep-DocumentAdd /></el-icon>
      </el-tooltip>
      <el-tooltip effect="dark" content="排序" placement="bottom" show-after="2000">
        <el-icon @click="clickSort"><i-ep-Sort /></el-icon>
      </el-tooltip>
      <el-tooltip effect="dark" content="刷新" placement="bottom" show-after="2000">
        <el-icon @click="clickRefresh"><i-ep-Refresh /></el-icon>
      </el-tooltip>
      <el-tooltip effect="dark" content="全书搜索" placement="bottom" show-after="2000">
        <el-icon @click="clickSearch"><i-ep-Search /></el-icon>
      </el-tooltip>
      <el-tooltip effect="dark" content="章节设置" placement="bottom" show-after="2000">
        <el-icon @click="clickChapterSetting"><i-ep-Setting /></el-icon>
      </el-tooltip>
    </div>
    <div class="chapter-manager-chapter-list">
      <el-scrollbar height="calc(100vh - 77px)">
        <el-tree
          :data="treeData"
          :props="defaultProps"
          :indent="0"
          node-key="id"
          :default-expanded-keys="['1']"
          :current-node-key="currentNodeKey"
          :highlight-current="true"
          empty-text="无章节数据"
          @node-click="handleTreeNodeClick"
        >
          <template #default="{ node, data }">
            <span @contextmenu="onContextMenu($event, node, data)" @mouseenter="hoverKey = data.id" @mouseleave="hoverKey = ''" class="custom-tree-node">
              <el-input v-if="currentEditKey === data.id" size="small" v-model="data.label" autofocus @blur="handleTreeNodeBlur(node, data)"></el-input>
              <span v-else>{{ data.label }}</span>
              <span v-if="data.children && data.label && currentEditKey !== data.id && hoverKey === data.id">
                <el-icon @click.stop="clickAddChapter"><i-ep-DocumentAdd /></el-icon>
                <el-icon style="margin-left: 10px" @click.stop="clickEditVolumeChapter(data, node)"><i-ep-Edit /></el-icon>
                <el-icon style="margin-left: 10px" @click.stop="clickDeleteVolume(data)"><i-ep-Delete /></el-icon>
              </span>
            </span>
          </template>
        </el-tree>
      </el-scrollbar>
    </div>
  </div>
  <ContextMenu v-model:visible="showContextMenu" :menu="contextMenu" :position="contextMenuPosition" @clickContextMenu="handleClickContextMenu" />
</template>

<script setup lang="ts">
/**
 * 章节管理器
 */
import { ref, reactive, onMounted } from "vue";
import Node from "element-plus/es/components/tree/src/model/node";
import { ElMessage, ElMessageBox } from "element-plus";
import "element-plus/es/components/message/style/css";
import "element-plus/es/components/message-box/style/css";

interface Tree {
  id: string;
  label: string;
  children?: Tree[];
  name?: string;
  path?: string;
  type?: string;
}
interface VolumesChapters {
  type: string;
  name: string;
  path: string;
  children?: VolumesChapters[];
}
interface ContextNodeData {
  node?: Node;
  data?: Tree;
}
interface Props {
  bookPath: string;
}
const props = withDefaults(defineProps<Props>(), {
  bookPath: "" // 书籍目录
});

const emit = defineEmits(["onChapterClick"]);

// 所有章节数据
let treeData = ref<Tree[]>([]);

const defaultProps = {
  children: "children",
  label: "label"
};

// 章节默认选中节点，即默认选中章节
const currentNodeKey = ref("1-1");
// 当前编辑节点的id
const currentEditKey = ref("");
// 当前编辑节点临时记录的旧名字
const currentEditOldLabel = ref("");
// 鼠标浮动到章节上的id
const hoverKey = ref("");
// 右键菜单列表
const contextMenu = ref([
  { key: "edit", name: "编辑" },
  { key: "delete", name: "删除" }
]);
// 是否展示右键菜单
const showContextMenu = ref(false);
// 右键菜单显示时的位置坐标
const contextMenuPosition = ref({ x: 0, y: 0 });
// 右键点击聚焦的节点数据
let contextNodeData = reactive<ContextNodeData>({});

onMounted(() => {
  // 获取对应书籍下的所有卷和章节
  init(true);
});

// 初始化查询卷章节数据
const init = (type?: boolean) => {
  if (props.bookPath) {
    window.electronAPI.readdir(props.bookPath).then((res: any) => {
      if (res && res.length) {
        const allVolumesAndChapters: any = [];
        res.forEach((ele: VolumesChapters) => {
          if (ele.type === "directory") {
            allVolumesAndChapters.push(ele);
          }
        });
        for (let i = 0; i < allVolumesAndChapters.length; i++) {
          for (let j = 0; j < allVolumesAndChapters[i].children.length; j++) {
            allVolumesAndChapters[i].children[j] = {
              ...allVolumesAndChapters[i].children[j],
              id: i + 1 + "-" + (j + 1),
              label: allVolumesAndChapters[i].children[j].name.split(".")[0] // 章节名字
            };
          }
          allVolumesAndChapters[i] = {
            ...allVolumesAndChapters[i],
            id: i + 1 + "",
            label: allVolumesAndChapters[i].name
          };
        }
        treeData.value = allVolumesAndChapters;
        if (type) {
          const lastChild = treeData.value[treeData.value.length - 1];
          if (lastChild && lastChild.children && lastChild.children.length) {
            currentNodeKey.value = lastChild.children[lastChild.children.length - 1].id;
            handleTreeNodeClick(lastChild.children[lastChild.children.length - 1]);
          } else {
            currentNodeKey.value = "1";
          }
        }
      }
    });
  }
};

let id = 1000;

// 监听右键，弹出右键菜单
const onContextMenu = (e: any, node: Node, data: Tree) => {
  if (!data.children || data.id.includes("-")) {
    contextNodeData = {
      node,
      data
    };
    showContextMenu.value = true;
    contextMenuPosition.value = {
      x: e.x || e.pageX,
      y: e.y || e.pageY
    };
  }
};

// 处理章节右键菜单项点击
const handleClickContextMenu = (key: string) => {
  showContextMenu.value = false;
  if (contextNodeData.data) {
    if (key === "edit") {
      clickEditVolumeChapter(contextNodeData.data);
    } else if (key === "delete") {
      clickDeleteChapter(contextNodeData.data);
    }
  }
};

// tree点击事件
const handleTreeNodeClick = (data: Tree) => {
  currentNodeKey.value = data.id;
  // 如果点击的是章节，将当前点击章节数据传给父组件
  if (data.id.includes("-") || !data.children) {
    emit("onChapterClick", data);
  }
};

// 点击新建卷
const clickAddVolume = () => {
  const newVolumeKey = treeData.value.length + 1 + "";
  treeData.value.push({
    id: newVolumeKey,
    label: "",
    children: []
  });
  currentEditKey.value = newVolumeKey;
};

// 新建卷或者新建章节输入框失去焦点
const handleTreeNodeBlur = (node: Node, data: Tree) => {
  const isVolume = !!data.children;
  if (isVolume) {
    const tempPath = props.bookPath + "/" + data.label;
    // 如果没有填写内容，失去焦点后删除该节点
    if (!data.label) {
      // 如果存在旧名字，重新赋值旧名字，否则删除卷
      if (currentEditOldLabel.value) {
        data.label = currentEditOldLabel.value;
        currentEditKey.value = "";
      } else {
        deleteVolume(node, data);
      }
    } else {
      // 新建的卷不能重名
      const hasSame = treeData.value.some((ele) => {
        return ele.id !== data.id && ele.label.trim() === data.label.trim();
      });
      if (hasSame) {
        ElMessage({
          message: "已存在相同名字的卷",
          type: "warning"
        });
      } else {
        // 如果存在旧名字，更新卷名称，否则，创建卷
        if (currentEditOldLabel.value) {
          const oldPath = data.path || props.bookPath + "/" + currentEditOldLabel.value;
          window.electronAPI.rename(oldPath, tempPath).then(() => {
            currentEditKey.value = "";
            currentEditOldLabel.value = "";
          });
        } else {
          window.electronAPI.mkdir(tempPath).then(() => {
            currentEditKey.value = "";
          });
        }
      }
    }
  } else {
    const parent = node.parent;
    const parentName = parent.data.label; // 当前编辑章节所属的卷名称
    let tempPath = props.bookPath + "/" + parentName + "/" + data.label + ".txt";
    if (!data.label) {
      if (currentEditOldLabel.value) {
        data.label = currentEditOldLabel.value;
        currentEditKey.value = "";
      } else {
        deleteVolume(node, data);
      }
    } else {
      const children: Tree[] = parent.data.children || parent.data;
      const hasSame = children.some((ele) => ele.id !== data.id && ele.label.trim() === data.label.trim());
      if (hasSame) {
        ElMessage({
          message: "已存在相同名字的章节",
          type: "warning"
        });
      } else {
        if (currentEditOldLabel.value) {
          const oldPath = data.path || props.bookPath + "/" + parentName + "/" + currentEditOldLabel.value + ".txt";
          window.electronAPI.rename(oldPath, tempPath).then(() => {
            currentEditKey.value = "";
            currentEditOldLabel.value = "";
          });
        } else {
          window.electronAPI.writeFile(tempPath, "").then(() => {
            currentEditKey.value = "";
          });
        }
      }
    }
  }
};

// 点击编辑卷，编辑章节
const clickEditVolumeChapter = (data: Tree, node?: Node) => {
  currentEditKey.value = data.id;
  currentEditOldLabel.value = data.label;
};

// 获取章节序号，第几章，第几集……
const getChapterNumber = (n: number) => {
  const chineseNumerals = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九", ""];
  const unit = ["", "十", "百", "千", "万"];
  const nStr = n.toString().split("").reverse();
  const newArr: string[] = [];
  nStr.forEach((ele, index) => {
    newArr.unshift(ele === "0" ? chineseNumerals[Number(ele)] : chineseNumerals[Number(ele)] + unit[index]);
  });
  let res = newArr.join("");
  res = res.replace("零零零", "零");
  res = res.replace("零零", "零");
  res = res.replace(/零+$/, "");
  res = res.replace(/^一十/g, "十");
  return res;
};

// 点击新建章
const clickAddChapter = () => {
  // 获取当前操作的卷的id
  const currentVolumeKey = currentNodeKey.value.split("-")[0];
  for (let i = 0; i < treeData.value.length; i++) {
    if (treeData.value[i].id === currentVolumeKey) {
      const chapters = treeData.value[i].children || [];
      const num = getChapterNumber(chapters.length + 1);
      const newChapterKey = treeData.value.length + 1 + "-" + (chapters.length + 1);
      const newChapterName = "第" + num + "章";
      treeData.value[i].children?.push({
        id: newChapterKey,
        label: newChapterName
      });
      currentEditKey.value = newChapterKey;
      // currentEditOldLabel.value = newChapterName;
      break;
    }
  }
};

// 点击排序，切换正序或倒序
const clickSort = () => {
  console.log("排序");
};

// 点击刷新，刷新章节卷数据
const clickRefresh = () => {
  init();
};

// 点击搜索，全书搜索关键词
const clickSearch = () => {
  console.log("搜索");
};

// 点击章节设置
const clickChapterSetting = () => {};

// 点击删除卷
const clickDeleteVolume = (data: Tree) => {
  ElMessageBox.confirm("此操作会删除该卷及卷下所有章节文件，你确认要删除吗?", "警告", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      if (data.path) {
        const res = await window.electronAPI.rmdir(data.path);
        if (res) {
          init();
        }
        ElMessage({
          type: "success",
          message: "已删除该卷及卷下所有文件"
        });
      }
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "已取消删除该卷"
      });
    });
};

// 点击删除章节
const clickDeleteChapter = (data: Tree) => {
  ElMessageBox.confirm("你确认要删除此章节吗?", "警告", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      if (data.path) {
        const res = await window.electronAPI.unlink(data.path);
        if (res) {
          init();
        }
        ElMessage({
          type: "success",
          message: "已删除该章节"
        });
      }
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "已取消删除该章节"
      });
    });
};

// 删除卷操作时删除treeData对应数据
const deleteVolume = (node: Node, data: Tree) => {
  const parent = node.parent;
  const children: Tree[] = parent.data.children || parent.data;
  const index = children.findIndex((d) => d.id === data.id);
  children.splice(index, 1);
  treeData.value = [...treeData.value];
};
</script>

<style lang="scss" scoped>
.chapter-manager {
  width: 230px;
  border-right: 1px solid var(--el-border-color);
  background-color: var(--el-bg-color);

  &-btns {
    padding: 15px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .el-icon {
      font-size: 20px;
      cursor: pointer;
    }
  }

  &-chapter-list {
    height: calc(100vh - 77px);
    overflow: hidden;

    .custom-tree-node {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
      padding-right: 15px;
      position: relative;
    }
  }
}
</style>
